#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using NoeticTools.StateEngine.Actions;
using NoeticTools.StateEngine.Conditions;
using NoeticTools.StateEngine.Logging;
using NoeticTools.StateEngine.Rules;
using NoeticTools.StateEngine.States;


namespace NoeticTools.StateEngine.Mapper
{
    public class StateEngineMapper<TContext, TState, TStateEvent> :
        IStateEngineMapper<TContext, TState, TStateEvent>
        where TContext : class
    {
        private readonly ICurrentState<TContext, TState, TStateEvent> currentState;
        private readonly IContextualLogManager logManager;
        private readonly IRuleBuilderFactory<TContext, TStateEvent> ruleBuilderFactory;
        private readonly IStateFactory<TContext> stateFactory;

        public StateEngineMapper(IStateMap<TContext, TState, TStateEvent> stateMap,
                                 IRuleBuilderFactory<TContext, TStateEvent> ruleBuilderFactory,
                                 ICurrentState<TContext, TState, TStateEvent> currentState,
                                 IStateFactory<TContext> stateFactory,
                                 IContextualLogManager logManager)
        {
            StateMap = stateMap;
            this.ruleBuilderFactory = ruleBuilderFactory;
            this.currentState = currentState;
            this.stateFactory = stateFactory;
            this.logManager = logManager;
        }

        public IStateMap<TContext, TState, TStateEvent> StateMap { get; private set; }

        public IRuleVerbsMapper<TContext, TState, TStateEvent> State(TState state)
        {
            return new RuleVerbsMapper<TContext, TState, TStateEvent>(this,
                                                                      ruleBuilderFactory.Create(
                                                                          StateMap.GetStateRules(state)),
                                                                      new ActionsFactory<TContext, TState, TStateEvent>(
                                                                          currentState, stateFactory, logManager),
                                                                      new ConditionsFactory<TStateEvent>());
        }

        public IAllStatesVerbsMapper<TContext, TState, TStateEvent> AllStates()
        {
            return new RuleVerbsMapper<TContext, TState, TStateEvent>(this,
                                                                      ruleBuilderFactory.Create(
                                                                          StateMap.GetAllStateRules()),
                                                                      new ActionsFactory<TContext, TState, TStateEvent>(
                                                                          currentState, stateFactory, logManager),
                                                                      new ConditionsFactory<TStateEvent>());
        }
    }
}